package com.hivision.codec;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.UnsupportedEncodingException;

public class ReportProcess {
    private String identifier; // 设备在应用协议里的标识

    private String msgType = "deviceReq"; // 固定值"deviceReq"，表示设备上报数据
    /**
     * 表示设备是否还有后续消息，0表示没有，1表示有，平台暂时不下发缓存命令，直到为0，下发缓存命令，不带按照0处理。
	 * 注：后续消息是指，设备上报的某条数据可能分成多次数据上报，在本次上报数据后，以hasMore字段判定后续是否还有消息。
	 * 请谨慎处理该字段，如果是必须数据上报后才有缓存命令下发的场景，只有某次数据上报时hasMore为0，缓存命令才能下发。
     */
    private int hasMore = 0;  
    private int errcode = 0;

    private String data;

    //serviceId=Electricity字段
    private double voltage = 0.0; // 电压
    private double current = 0;  // 电流
    private double electricityConsumption; // 用电量
//    private double frequency = 0.0; // 
//    private double powerfactor = 0.0;

    //serviceId=Temperature字段
    private double temperature = 0; // 温度
    private double humidity = 0; // 湿度
    private double illuminance=0; // 光照度
    
    //serviceId=Brightness字段
    private int brightness = 0; // 亮度
    private int signalIntensity; // 信号强度
    private int errorRate; // 误码率

    private byte noMid = 0x00;
    private byte hasMid = 0x01;
    private boolean isContainMid = false;
    private int mid = 0;
    private String uid;
    
    private int alarmType; // 报警类型
    private int cmdCode; // 指令码
    private final int CMDCODE_INDEX = 16; // 指令码字节的位置索引
    
    private int heartBeatIntervel; // 心跳间隔
    private int uploadInterval; // 数据上报间隔
    private double maxVoltagethreshold; // 过压阈值
    private double minVoltagethreshold; // 欠压阈值
    private String iotIp; // IOT平台IP地址
    private int iotPort;  // IOT平台端口

    /**
     * @param binaryData 设备发送给平台coap报文的payload部分
     *                   本例入参：AA 72 00 00 32 08 8D 03 20 62 33 99
     *                   byte[0]--byte[1]:  AA 72 命令头
     *                   byte[2]:   00 mstType 00表示设备上报数据deviceReq
     *                   byte[3]:   00 hasMore  0表示没有后续数据，1表示有后续数据，不带按照0处理
     *                   byte[4]--byte[11]:服务数据，根据需要解析//如果是deviceRsp,byte[4]表示是否携带mid, byte[5]--byte[6]表示短命令Id
     * @return
     */
    public ReportProcess(byte[] binaryData) {
    	try {
            this.data = Utilty.parseByte2HexStr(binaryData);

    		this.identifier = Utilty.getInstance().parseByte2AscStr(binaryData, 6, 8);
        	
        	// 指令码
        	this.cmdCode = Utilty.getInstance().bytes2Int(binaryData, CMDCODE_INDEX, 2);
            //此处需要考虑兼容性，如果没有传mId，则不对其进行解码
            this.mid = Utilty.getInstance().bytes2Int(binaryData, CMDCODE_INDEX-2, 2);
            //uid
            this.uid = Utilty.getInstance().parseByte2AscStr(binaryData, 6, 8);

		} catch (Exception e) {
			e.printStackTrace();
		}
    }

    public ObjectNode toJsonNode() {
        try {
            //组装body体
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode root = mapper.createObjectNode();

            root.put("identifier", this.identifier);
            root.put("msgType", this.msgType);
            root.put("hasMore", this.hasMore);

            ObjectNode node = mapper.createObjectNode();
            node.put("serviceId", "ReportService");
            ObjectNode nodeData = mapper.createObjectNode();
            nodeData.put("cmdCode", this.cmdCode);
            nodeData.put("mid", this.mid);
            nodeData.put("data", this.data);
            node.put("serviceData", nodeData);

            ArrayNode arrynode = mapper.createArrayNode();
            arrynode.add(node);

            root.put("data", arrynode);

            return root;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}